package com.skd.mall.ware.service.impl;

import com.mysql.cj.util.StringUtils;
import com.skd.common.dto.SkuHasgStockDto;
import com.skd.mall.ware.execption.NoStockExecption;
import com.skd.mall.ware.fegin.ProductFeignService;
import com.skd.mall.ware.vo.LockStockResult;
import com.skd.mall.ware.vo.OrderItemVo;
import com.skd.mall.ware.vo.WareSkuLockVO;
import lombok.Data;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.skd.common.utils.PageUtils;
import com.skd.common.utils.Query;

import com.skd.mall.ware.dao.WareSkuDao;
import com.skd.mall.ware.entity.WareSkuEntity;
import com.skd.mall.ware.service.WareSkuService;
import org.springframework.transaction.annotation.Transactional;


@Service("wareSkuService")
public class WareSkuServiceImpl extends ServiceImpl<WareSkuDao, WareSkuEntity> implements WareSkuService {

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        QueryWrapper<WareSkuEntity> wrapper =new QueryWrapper<>();
        String skuId = (String) params.get("skuId");
        if(!StringUtils.isEmptyOrWhitespaceOnly(skuId)){
            wrapper.eq("sku_id",skuId);
        }
        String wareId = (String) params.get("wareId");
        if (!StringUtils.isEmptyOrWhitespaceOnly(wareId)){
            wrapper.eq("ware_id",wareId);
        }
        IPage<WareSkuEntity> page = this.page(
                new Query<WareSkuEntity>().getPage(params),
                wrapper
        );

        return new PageUtils(page);
    }

    @Autowired
    private WareSkuDao wareSkuDao;
    @Autowired
    private ProductFeignService productFeignService;
    @Override
    public void addStock(Long skuId, Long wareId, Integer skuNum) {
        System.out.println(skuId+"--"+wareId+"--"+skuNum);
        WareSkuEntity wareSkuEntity = wareSkuDao.selectOne(
                new QueryWrapper<WareSkuEntity>().eq("sku_id", skuId).eq("ware_id", wareId));
        if(wareSkuEntity==null){//如果没有入库记录
            WareSkuEntity skuEntity = new WareSkuEntity();
            skuEntity.setSkuId(skuId);
            skuEntity.setWareId(wareId);
            skuEntity.setStock(0);
            skuEntity.setStock(skuNum);
            skuEntity.setSkuName(productFeignService.name(skuId));
            wareSkuDao.insert(skuEntity);
        }else{//有入库记录
            wareSkuEntity.setSkuName(productFeignService.name(skuId));
            Integer beforeStock = wareSkuEntity.getStock();
            wareSkuEntity.setStock(beforeStock+skuNum);
            wareSkuDao.updateById(wareSkuEntity);
        }
    }

    @Override
    public List<SkuHasgStockDto> getSkusHasStock(List<Long> skuIds) {
        List<SkuHasgStockDto> stockDtos = skuIds.stream().map(skuId -> {
            System.out.println(skuId);
            SkuHasgStockDto dto = new SkuHasgStockDto();
            WareSkuEntity wareSkuEntity = wareSkuDao.selectOne(
                    new QueryWrapper<WareSkuEntity>().eq("sku_id", skuId));
            Boolean hasStock = wareSkuEntity.getStock() - wareSkuEntity.getStockLocked() > 0 ? true : false;
            dto.setSkuId(skuId);
            dto.setHasStock(hasStock);
            return dto;
        }).collect(Collectors.toList());
        return stockDtos;
    }

    /**
     * 锁定库存
     * @param vo
     * @return
     */
    @Transactional
    @Override
    public Boolean orderLockStock(WareSkuLockVO vo) throws NoStockExecption{
        List<OrderItemVo> items = vo.getItems();
        List<SkuWareHasStock> collect = items.stream().map(item -> {
            SkuWareHasStock skuWareHasStock = new SkuWareHasStock();
            skuWareHasStock.setSkuId(item.getSkuId());
            List<WareSkuEntity> wareSkuEntities = wareSkuDao.listHashStock(item.getSkuId());
            skuWareHasStock.setWareId(wareSkuEntities);
            skuWareHasStock.setNum(item.getCount());
            return skuWareHasStock;
        }).collect(Collectors.toList());
        for (SkuWareHasStock skuWareHasStock : collect) {
            Long skuId = skuWareHasStock.getSkuId();
            List<WareSkuEntity> wareSkuEntities = skuWareHasStock.getWareId();
            if(wareSkuEntities.size() == 0){
                //没有库存了
                throw new NoStockExecption(skuId);
            }
            //当前要锁定的商品的数量
            Integer count = skuWareHasStock.getNum();
            Boolean skuStock = false;//表示当前SKUid没有锁定库存
            for (WareSkuEntity wareSkuEntity : wareSkuEntities) {
                //循环过去对应的仓库 然后锁定
                //获取当前仓库库存数量
                Integer canStock = wareSkuEntity.getStock() - wareSkuEntity.getStockLocked();
                WareSkuEntity entity = new WareSkuEntity();
                BeanUtils.copyProperties(wareSkuEntity,entity);
                if(count<=canStock){
                    //当前商品需求数量小于需要锁定数量
                    entity.setStockLocked(wareSkuEntity.getStockLocked()+count);
                    Integer i = wareSkuDao.updateById(entity);
                    count = 0;
                    skuStock = true;
                }else {
                    //当前商品需求数量大于需要锁定数量
                    entity.setStockLocked(wareSkuEntity.getStock());
                    Integer i = wareSkuDao.updateById(entity);
                    count= count-canStock;
                }
                if (count<=0){
                    //表示商品都锁定了
                    break;
                }

            }
            if(skuStock == false){
                throw new NoStockExecption(skuId);
            }
        }
        return true;
    }

    /**
     * 更新库存
     * @param orderItemVos
     */
    @Transactional
    @Override
    public void updateStock(List<OrderItemVo> orderItemVos) {
        //一个订单只更新一次
        List<WareSkuEntity> wareSkuEntities = new ArrayList<>();
        for (OrderItemVo orderItemVo : orderItemVos) {
            //查询库存信息
            List<WareSkuEntity> wareStocks = this.list(
                    new QueryWrapper<WareSkuEntity>().eq("sku_id", orderItemVo.getSkuId())
            );
            Integer count = orderItemVo.getCount();
            for (WareSkuEntity wareStock : wareStocks) {
                //一个仓库的锁定数量就足够了
                if(wareStock.getStockLocked()>=count && count!=0){
                    wareStock.setStockLocked(wareStock.getStockLocked()-count);
                    wareStock.setStock(wareStock.getStock()-count);
                    wareSkuEntities.add(wareStock);
                    count = 0;
                }else {
                    //一个仓库不够
                    count = count - wareStock.getStockLocked();
                    wareStock.setStock(wareStock.getStock()-wareStock.getStockLocked());
                    wareStock.setStockLocked(0);
                    wareSkuEntities.add(wareStock);
                }
            }
            //更新库存
            boolean b = this.updateBatchById(wareSkuEntities);
        }

    }

    @Data
    class SkuWareHasStock{
        private Long skuId;
        private Integer num;
        private List<WareSkuEntity> wareId;
    }
}